home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-02-20 | 67.7 KB | 1,551 lines | [TEXT/MPS ] |
- /*------------------------------------------------------------------------------
- #
- # Apple Developer Technical Support
- #
- # Edition Manager Sample Application
- #
- # EditionSample
- #
- # main.c - C Source
- #
- # Copyright © 1990,1991 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 2.0ß1 02/91 C.K. Haun <TR>
- #
- # Components:
- # main.c
- # Menu.c
- # Files.c
- # Publish.c
- # Subscribe.c
- # TextSections.c
- # Windows.c
- # AppleEventM.c
- # EditionSample.make
- # EditionSample.r
- # FinderIcons.r
- # EdSampdefines.h
- # BuildHeaders.c
- #
- #
- # This is an example of using the Edition Manager in a multi-windowed
- # application.
- # This sample contains most of the Edition Manager calls that
- # you'll need in your application. It also contains one method
- # for keeping track of the edition data for all your documents.
- # It does NOT by any means demonstrate all the techniques
- # you need for a large application, nor the best data handling
- # methods for all cases.
- # Use this sample as a starting point, and adapt its' routines to
- # meet the specific needs of your project.
- # This sample will grow as more edition types are implemented,
- # periodically check AppleLink for a later, expanded sample.
- # This application is an example of the form of a Macintosh
- # application; it is NOT a template. It is NOT intended to be
- # used as a foundation for the next world-class, best-selling,
- # 600K application. A stick figure drawing of the human body may
- # be a good example of the form for a painting, but that does not
- # mean it should be used as the basis for the next Mona Lisa.
- #
- #
- ------------------------------------------------------------------------------*/
- /*****************************************************************
- We here at DTS believe that good sample code is one of the best tools
- we can provide to help make your jobs easier. And we want the
- code we provide to be the best possible, and to be the most useful.
- You can help us.
- Please take a few minutes and answer the following questions about this
- piece of sample code. When you're done, cut out the survey and
- send it to the AppleLink account DTS.FEEDBACK,
- internet DTS.FEEDBACK@AppleLink.apple.com
- or by US mail to;
- DTS Sample Code Feedback
- 20525 Mariani Ave., MS: 75-3T
- Cupertino, CA 95014
- We won't be able to answer individual feedback messages, but you'll
- see the difference in the code we put out.
- Your answers will help us help you write fantastic applications!
-
- -------------------------------- cut here ---------------------------------
- 1) Sample goals
- All our sample code is written to meet a need, to show a specific manager
- or system feature.
- Does this sample you're now looking at meet it's objectives? Does it show
- you the features of the Edition Manager that you need to write your
- application? If not, please tell us what we could do better.
-
-
- 2) Sample Organization
- Is this sample organized in a manner that makes it easy for you to find the
- information you need? If you're looking for a particular routine or
- trap call, can you find it quickly or do you have to search too much?
- Any organizational comments on file names, MPW marks, function names, or
- anything else?
-
-
- 3) Useability
- Can you use the code in this sample in your application? We'd love for
- all our sample code to be 'cut and paste' code that you can drop right into
- your code, did we meet that goal (language differences aside)?
-
-
- 4) Programmer's Style
- Programming is an individual art, and every programmer writes code differently.
- But some coding styles can hide more than they help.
- Could you follow the logic of the programmer of this sample? Was the point of
- the code clear, not hidden by language peculiarities?
-
-
- 5) Program line Comments
- Are there enough comments in this sample? Are there too many comments?
- Did the comments in the code help you clearly understand the process and logic?
-
-
- 6) Building
- Did this sample compile? Did you have any problem building and running this
- sample (in the environment it was meant to be built/run under)?
-
-
- 7) Bugs
- And of course, were there any bugs?
-
-
- 8) Your wish list
- What other specific areas would you like to see covered in DTS sample code?
-
-
- 9 - ∞) Any additional comments?
-
-
- -------------------------------- cut here ---------------------------------
- Again, thanks a lot for any and all feedback you can send us. Your input
- will shape our future code; the more information you can give us the
- better service we can provide to you.
-
- Apple Developer Tech Support
- ***********************************************************************/
-
-
- /* Picture display and publisher */
- /* will be extended to be a text and private pub pub pub pppppub */
- #define __SAMPMAIN__
-
- #pragma segement Main
- #pragma load "EdSampheaders" /* see the Buildheaders.c file */
-
- #include "EdSampdefines.h"
-
- /* prototypes for this file */
- void CloseMyWindow(WindowPtr theClose);
- void DoDiskEvents(long dinfo);
- void DrawIt(void);
- void StartStuff(void);
- void UndoLast(void);
- void DrawMe(void);
- WindowPtr AddNewWindow(Boolean showIt);
- Boolean SearchPubs(Point thePoint);
- Boolean SearchSubs(Point thePoint);
- void ShowMe(Str255 in, OSErr aevtErr);
- void DrawFull(windowCHandle theWind, WindowPtr theWindPtr);
- void AddLine(windowCHandle nowHandle, myLine *inline);
- void AddRect(windowCHandle nowHandle, Rect *inrect);
- void AddTextBox(windowCHandle nowHandle, Rect *inrect);
- void AddOval(windowCHandle nowHandle, Rect *inoval);
- void AddSelection(windowCHandle nowHandle, Rect *inrect);
- void AdjustCursor(Point mouse, RgnHandle region, Boolean isAppleEvent);
- void DoDocumentClick(WindowPtr twindow);
- void PullRect(windowCHandle theWind, Rect *startRect, Boolean isOval, Boolean useRect);
- void CreateClipBoard(void);
- extern void DrawClip(WindowPtr windowIn);
- extern void ClipClick(WindowPtr twindow);
- extern void CloseClip(void);
- extern void UpdateScrap(void);
- extern void SpitClip(void);
- void DeBorderSelection(void);
- OSErr MySetHandleSize(Handle theHandle, Size theSize);
- Boolean InTextBox(windowCHandle inName, Rect *where);
- void MakeRect(Point *aPoint, Point *bPoint, Rect *putRect);
- Boolean PureCursor(char theKey);
- /* external references */
- extern void SaveMe(windowCHandle theWind, WindowPtr theWindPtr);
- extern Boolean DoSelected(long val);
- extern ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem);
- extern void PopMenu(Point tp);
- extern void WriteNum(long numtowrite);
- extern void DoHighLevel(EventRecord AERecord);
- extern void InitAEStuff(void);
- extern void SetUndo(short undoNow, Boolean fromRecord);
- extern void DoOptions(SectionHandle inSection);
- extern void SetWMenus(Boolean how);
- extern void AdjustMenus(windowCHandle tempCH);
- extern void KillClipSub(void);
- extern void _DataInit();
- extern OSErr MyGoToPublisher(SectionHandle theSection);
- extern void CheckTextSections(windowCHandle inWindow, short Action);
- extern Boolean SkipOverSubscriber(windowCHandle inWindow, unsigned short theKey);
- extern void CheckSectionHit();
- extern void ExcludeSubscriber(windowCHandle tempCH);
- extern void BorderTextSection(textSectionHandle theText);
- extern void ChangePlane(WindowPtr twindow);
- extern Boolean IsDAWindow(WindowPtr window);
- extern Boolean IsAppWindow(WindowPtr window);
- extern WindowPtr AddNewWindow(Boolean showIt);
- extern void CloseMyWindow(WindowPtr theClose);
- /* globals */
-
- Handle gMymenu; /* my menu bar handle */
- Handle gScrapData; /* picture data currently on clipboard */
- /* individual menu handles */
- MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle, gAdditionalMenu;
- Boolean gStop; /* Stop flag for this app */
- WindowPtr gCurrentWindow = nil; /* window currently frontmost */
- WindowPtr gClipWindowPtr = nil; /* our clipboard window */
- WindowPtr gActionWindows = nil; /* start of our window list */
- short gWindowCount = 0; /* current number of windows, since I'm restricting to 10 */
- unsigned long gMasterWindowID = 10000; /* for section tracking */
- Rect gShowPubRect; /* rectangle of the currently selected publisher */
- Rect gShowSubRect; /* rectangle of the currently selected subscriber */
- SectionHandle gShowingSecHandle = nil; /* currently selected section */
- SectionHandle gClipSection = nil; /* if the clipboard contains a section */
- PicHandle gClipPict; /* for the section picture */
- Boolean gShowPub = false; /* telling if a publisher or subscriber */
- Boolean gShowSub = false; /* border should be displayed */
- Boolean gShowingAll = false; /* show all borders toggle */
- Boolean gInBackground = false; /* Where Are We? */
- Boolean gExpanded = false; /* flag for expanded dialogs, for this sample */
- Boolean gResizeSub = false; /* resize flag for this sample */
- short gClipHasContents = kClipEmpty; /* indicates the contents of the clipboard (PICT, TEXT, section ) */
- EventRecord gERecord; /* guess */
- ProcessSerialNumber gOurSN; /* serial number of this process (us, our application) */
- Boolean gHasAppleEvents; /* not really necessary, since we fail if these */
- Boolean gHasEditionManager; /* aren't available, but it's only two bytes.... */
- Boolean gHasSelection = false; /* for publish menu item */
- Boolean gEdSamp = false; /* allow subscription to MacPaint files */
- EditionOpenerProcPtr gOriginalOpener; /* for custom opener, later.... */
-
- short actsToIDs[6] = /* converts my action codes to tool menu item IDs */
- {
- 0, 1, 2, 3, 4, 6
- };
-
-
-
-
- long aLong;
- SectionHandle lastSection; /* for double click testing */
- unsigned long lastSecClickTick;
-
- main()
- {
- WindowPtr twindow;
- Boolean x;
- Boolean menuAction;
- windowCHandle tempCH; /* temporary var */
- RgnHandle mousergn; /* for WaitNextEvent */
- PScrapStuff theScrap;
- short myScrapCount = 999; /* intialize to a silly value */
- UnloadSeg((Ptr)_DataInit); /* throw the bums out */
- StartStuff(); /* initialize managers and normal startup actions */
- UnloadSeg((Ptr)StartStuff);
- theScrap = InfoScrap();
- FlushEvents(everyEvent, 0);
- mousergn = NewRgn();
- gStop = false;
- while (!gStop) {
- x = WaitNextEvent(everyEvent, &gERecord, 30, mousergn);
- theScrap = InfoScrap();
- if (theScrap->scrapCount != myScrapCount) {
- myScrapCount = theScrap->scrapCount;
- UpdateScrap();
- }
- if (gCurrentWindow != nil) {
- TEHandle tempTE;
- windowCHandle tempCH = (windowCHandle)GetWRefCon(gCurrentWindow);
- tempTE = (*tempCH)->boxHandle;
- if (tempTE != nil)
- TEIdle(tempTE);
- }
- AdjustCursor(gERecord.where, mousergn, (gERecord.what == kHighLevelEvent));
- switch (gERecord.what) {
- case nullEvent:
- /* no nul processing in this sample */
- break;
- case updateEvt:
- DrawIt(); /* draw whatever window needs an update */
- break;
- case mouseDown:
- /* first see where the hit was */
- switch (FindWindow(gERecord.where, &twindow)) {
- case inDesk: /* if they hit in desk, then the process manager */
- break; /* will switch us out, we don't need to do anything */
- case inMenuBar:
- /* If they clicked in the menu bar, we need to set up the Undo */
- /* text string for the current window, and the toggle of */
- /* Publisher or Subscriber options before we drop the */
- /* menu down. */
- /* Also change the Save string depending on the save state */
- /* Pull our aux data structure out of the current window */
- if (gCurrentWindow) {
- tempCH = (windowCHandle)GetWRefCon(gCurrentWindow);
- HLock((Handle)tempCH); /* lock it */
- gHasSelection = (*tempCH)->hasSelection;
- AdjustMenus(tempCH); /* in menu.c */
- HUnlock((Handle)tempCH);
- } else {
- AdjustMenus(nil);
- }
- /* Now we drop the menu down, and pass the results */
- /* to our menu handler (in Menu.c) */
- DoSelected(MenuSelect(gERecord.where));
- break;
- case inSysWindow:
- /* pass to the system */
- SystemClick(&gERecord, twindow);
- break;
- case inContent:
- /* Our major workarea. Depending on other factors, a */
- /* user could be drawing, moving a subscriber, selecting */
- /* a publisher or subscriber, selecting an area, or nothing. */
- /* First, if they did not click in the front window, we need */
- /* to bring the window they did click in to the front, and */
- /* pull the information we need (cursor mode, undo action, etc. ) */
- /* out of the aux record and update things */
- if (twindow != FrontWindow()) {
- ChangePlane(twindow);
- } else {
- if (gCurrentWindow) { /* don't do this unless we have a window open, silly */
- windowCHandle clicker;
- clicker = (windowCHandle)GetWRefCon(twindow);
- /* jump to the content function stored for this window */
- HLock((Handle)clicker); /* lock it down so things don't get stupid */
- (ProcPtr)((*clicker)->clickMe)(twindow);
- HUnlock((Handle)clicker); /* all done */
- }
- }
- break;
- case inDrag:
- DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
- break;
- case inGrow:
- case inGoAway:
- /* Track a click in the go away box. If the user stays in it, */
- /* call the close proc for this window */
- if (TrackGoAway(twindow, gERecord.where))
- (ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
- break;
-
- }
- case mouseUp:
- /* don't care */
- break;
- /* same action for key or auto key */
- case keyDown:
- case autoKey:
- /* Do menu commands. */
- /* Also check the window record for a TextEdit field, if there */
- /* is one pass the key to it */
- if (gERecord.modifiers & cmdKey) {
- if (gCurrentWindow) {
- tempCH = (windowCHandle)GetWRefCon(gCurrentWindow);
- HLock((Handle)tempCH); /* lock it */
- gHasSelection = (*tempCH)->hasSelection;
- AdjustMenus(tempCH); /* in menu.c */
- HUnlock((Handle)tempCH);
- } else {
- AdjustMenus(nil);
- }
- DoSelected(MenuKey(gERecord.message & charCodeMask));
- } else {
- WindowPtr tempWP = FrontWindow();
- tempCH = (windowCHandle)GetWRefCon(tempWP);
- if (IsAppWindow(tempWP) && ((*tempCH)->boxHandle != nil)) {
- Boolean wasPC = false;
- tempCH = (windowCHandle)GetWRefCon(tempWP);
- if ((*tempCH)->textSections != nil) {
- /* this text box has sections, and the sections may need to be */
- /* adjusted by this keystroke. First, see if it's a pure cursor move, */
- if (wasPC = PureCursor(gERecord.message & charCodeMask))
- wasPC = SkipOverSubscriber(tempCH, gERecord.message & charCodeMask);
- else
- CheckTextSections(tempCH, kKeyStroke);
- }
- if (!wasPC) {
- /* ExcludeSubscriber shortens the current selection if it impact on any */
- /* subscribers */
- ExcludeSubscriber(tempCH);
- TEKey(gERecord.message & charCodeMask, (*tempCH)->boxHandle);
- }
- }
- }
- break;
- case keyUp:
- /* don't care */
- break;
- case diskEvt:
- /* I don't do anything special for disk events, this just passes them */
- /* to a function that checks for an error on the mount */
- DoDiskEvents(gERecord.message);
- break;
- case activateEvt:
- /* Draws on a window activate. Other activate/deactivate stuff is */
- /* handled in either the ChangePlane function (for normal shuffling ) */
- /* or in the suspend/resume handler for layer swaps */
- if (gERecord.modifiers & activeFlag)
- DrawIt();
- break;
- case networkEvt:
- /* don't care */
- break;
- case driverEvt:
- /* don't care */
- break;
- case app4Evt:
- switch ((gERecord.message >> 24) & 0x0FF) { /* high byte of message */
- case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (gERecord.message & kResumeMask) == 0;
- if (gInBackground) {
- SpitClip(); /* export the clipboard please */
- /* deactivate the current TextEdit record as necessary */
- if (gCurrentWindow != nil) {
- windowCHandle tempCH = (windowCHandle)GetWRefCon(gCurrentWindow);
- if ((*tempCH)->boxHandle != nil)
- TEDeactivate((*tempCH)->boxHandle);
- }
- if (gShowSub || gShowPub) {
-
- }
- } else {
- if (gCurrentWindow != nil) {
- windowCHandle tempCH = (windowCHandle)GetWRefCon(gCurrentWindow);
- if ((*tempCH)->boxHandle != nil)
- TEActivate((*tempCH)->boxHandle);
- }
- }
- break;
- }
- break;
- default:
- break;
- /* This dispatches high level events (AppleEvents, for example) */
- /* to our dispatch routine. This is NEW in the event loop for */
- /* System 7 */
- case kHighLevelEvent:
- DoHighLevel(gERecord);
- break;
-
- }
- }
- }
-
- /* DrawIt calls the drawing routine for the window that requires a refresh,
- * either for a update or activate
- */
- void DrawIt(void)
- {
- WindowPtr nowwind, tempwind;
- windowCHandle drawers;
- GetPort(&tempwind); /* save the current port */
- nowwind = (WindowPtr)gERecord.message; /* get the port referenced by
- this event */
- BeginUpdate(nowwind); /* tell window manager to do it's thing */
- SetPort(nowwind);
- EraseRgn(nowwind->visRgn); /* erase whatever needs updating, remember that
- BeginUpdate copies the update region into the visRgn */
- /* pull our control structure out of the refCon */
- drawers = (windowCHandle)GetWRefCon(nowwind);
- HLock((Handle)drawers); /* lock it down so things don't get stupid */
- /* jump to the drawing function stored for this window */
- (ProcPtr)((*drawers)->drawMe)(drawers, nowwind);
- HUnlock((Handle)drawers); /* all done */
- EndUpdate(nowwind); /* all done */
- SetPort(tempwind); /* reset the port to the entry port */
- }
-
- /* DrawIt */
-
- /* UndoLast undoes the last drawing action that happened in the current
- * window. Each window has it's own record of the last action, so
- * Undo is always valid for the current window, and will not act on a
- * window the user doesn't expect. */
- void UndoLast(void)
- {
- windowCHandle temp;
- WindowPtr tempPort;
- GetPort(&tempPort); /* not really necessary, but I'm paranoid */
- SetPort(gCurrentWindow);
- temp = (windowCHandle)GetWRefCon(gCurrentWindow);
- HLock((Handle)temp); /* memory may move when handles are resized */
- switch ((*temp)->undoAction) { /* last action that happened in this window */
- /* For the graphic objects, we need to erase the last thing draw and update
- * the window record's handles and counts */
- case kDrawLine:
- HUnlock((Handle)(*temp)->lineList);
- (*temp)->lineCount--;
- MySetHandleSize((Handle)(*temp)->lineList, GetHandleSize((Handle)(*temp)->lineList) - sizeof(myLine));
- break;
- case kDrawRect:
- (*temp)->rectCount--;
- HUnlock((Handle)(*temp)->rectList);
- MySetHandleSize((*temp)->rectList, GetHandleSize((*temp)->rectList) - sizeof(Rect));
- break;
- case kDrawOval:
- (*temp)->ovalCount--;
- HUnlock((Handle)(*temp)->ovalList);
- MySetHandleSize((*temp)->ovalList, GetHandleSize((*temp)->ovalList) - sizeof(Rect));
- break;
- case kTextBox:
- TEDispose((*temp)->boxHandle);
- (*temp)->boxHandle = nil;
- InsetRect(&(*temp)->textBox, -3, -2); /* just don't ask */
- InvalRect(&(*temp)->textBox);
- break;
- case kSelectStuff:
- (*temp)->hasSelection = false;
- break;
- }
- HUnlock((Handle)temp);
- /* now make sure things get refreshed */
- InvalRect(&(gCurrentWindow->portRect));
- EraseRect(&(gCurrentWindow->portRect));
- SetUndo(0, false);
- SetPort(tempPort);
- }
-
-
-
- /* In SearchPubs we'll search the publishers in this window for a publisher */
- /* that was clicked in. If we find one, hilite it and outline it. */
- /* Point is already in local coordinates */
- Boolean SearchPubs(Point thePoint)
- {
- register qq;
- Rect rectToCheck;
- Rect cornerRect;
- Rect *theRects;
- Boolean gotIt = false;
- windowCHandle shortname = (windowCHandle)GetWRefCon(gCurrentWindow);
- HLock((Handle)shortname);
- if ((*shortname)->numPubs) { /* does this window have any publishers? */
- /* yes, see if one was clicked in */
- HLock((*shortname)->pubRects); /* lock the rect handle down */
- theRects = (Rect *)*(*shortname)->pubRects;
- /* dereference it and cast it to a rect pointer so checking will be
- * conceptually easier (i.e. you can read it)
- */
- for (qq = 0; qq < (*shortname)->numPubs; qq++) { /* step through 'em */
- SectionHandle *tempPtr;
- rectToCheck = *theRects;
- if (PtInRect(thePoint, &rectToCheck)) { /* thePoint is coming from your */
- /* last event record */
- /* We've found a section that has been clicked in */
- if (gShowPub && (rectToCheck != gShowPubRect))
- InvalRect(&gShowPubRect); /* clear previous, if there was one */
- gShowPub = true;
- if (gShowSub) /* clear previous, if there was one */ {
- InvalRect(&gShowSubRect);
- gShowSub = false;
- }
- /* make sure the border gets draw next update */
- InsetRect(&rectToCheck,-4,-4);
- InvalRect(&rectToCheck);
- InsetRect(&rectToCheck,4,4);
- /* we've found it with it's rectangle, so now dig out the */
- /* section handle */
- HLock((*shortname)->pubs);
- tempPtr = (SectionHandle *)*(*shortname)->pubs;
- tempPtr += qq;
- /* and move the section handle into our global variable that */
- /* contains the currently highlighted section, so we can */
- /* access it from the Options function and dialog */
- gShowingSecHandle = *tempPtr;
- /* done with the pointer handle */
- HUnlock((*shortname)->pubs);
- /* change the menu item name now */
- SetItem(gEditMenuHandle, kSoptionsItem, "\pPublisher Options...");
- gShowPubRect = rectToCheck;
- gotIt = true;
- /* Now we need to stretch the thing if the user wants too, I guess */
- /* See if it was in the corner rect first */
- cornerRect = gShowPubRect;
- cornerRect.top = cornerRect.bottom - 7;
- cornerRect.left = cornerRect.right - 7;
- if (PtInRect(thePoint, &cornerRect)) {
- PullRect(shortname, &gShowPubRect, false, true);
- if (*theRects != gShowPubRect) {
- *theRects = gShowPubRect;
- InvalRect(theRects);
- }
- }
- }
- if (gotIt)
- break;
- theRects++; /* increase by one Rect */
- }
- HUnlock((*shortname)->pubRects);
- }
- HUnlock((Handle)shortname);
- return(gotIt);
- }
-
- /* end SearchPubs */
-
- /* Searches the subcriber list, hilites the selection, and drags it */
- /* This is very similar to the publisher check, but has added functionality */
- /* for dragging the subscriber around the window */
- Boolean SearchSubs(Point thePoint)
- {
- register qq;
- Handle *theRectsHandle;
- Boolean subGotIt = false;
- windowCHandle shortname = (windowCHandle)GetWRefCon(gCurrentWindow);
- HLock((Handle)shortname);
- if ((*shortname)->numSubs) { /* does it have any subscribers? */
- HLock((*shortname)->subRects); /* lock down the rect handle */
- /* cast it as a pointer to handles for reading ease */
- theRectsHandle = (Handle *)*(*shortname)->subRects;
- for (qq = 0; qq < (*shortname)->numSubs; qq++) { /* step through the subscribers */
- SectionHandle *tempPtr;
- Rect *checkRect;
- Rect cornerRect;
- HLock(*theRectsHandle);
- checkRect = (Rect *)**theRectsHandle;
- /* did they click in this rect? */
- InsetRect(checkRect, -4, -4); /* include the possible borders */
- if (PtInRect(thePoint, checkRect)) { /* yes */
- /* erase the old display rectangles, if there are any */
- if (gShowSub)
- InvalRect(&gShowSubRect);
- gShowSub = true;
- if (gShowPub) {
- InvalRect(&gShowPubRect);
- gShowPub = false;
- }
- /* get the section handle for this section */
- HLock((*shortname)->subs);
- tempPtr = (SectionHandle *)*(*shortname)->subs;
- tempPtr += qq;
- gShowingSecHandle = *tempPtr;
- HUnlock((*shortname)->subs);
- /* change the menu item name now */
- SetItem(gEditMenuHandle, kSoptionsItem, "\pSubscriber Options...");
- InvalRect(checkRect); /* make sure it gets redrawn */
- /* now I want the actual rect values so I can drag it around */
- /* in response to the user */
- gShowSubRect = *checkRect;
- PenPat(qd.dkGray);
- PenSize(3, 3);
- FrameRect(&gShowSubRect);
- PenSize(1, 1);
- /* Here you drag the thing around to where the user wants it, updating the
- * window record as you do it. */
- GetMouse(&thePoint);
- InvalRect(&gShowSubRect);
- /* two choices here. They could be dragging the whole thing, or resizing it. */
- /* The resize box is in the lower right ten pixels, I'll say, so if the original */
- /* click is there I'll go to the resize routine */
- cornerRect = gShowSubRect;
- cornerRect.top = cornerRect.bottom - 7;
- cornerRect.left = cornerRect.right - 7;
- if (PtInRect(thePoint, &cornerRect) && gResizeSub) {
-
- PullRect(shortname, &gShowSubRect, false, true);
-
- } else {
- while (StillDown()) { /* keep doing it until they release the mouse */
- Point tempPoint;
- PenMode(patXor);
- FrameRect(&gShowSubRect); /* nasty way to put up a flashing border for the drag */
- FrameRect(&gShowSubRect);
- GetMouse(&tempPoint);
- /* keep inside the window please, don't let them drag the */
- /* rectangle outside the window bounds */
- if (PtInRect(tempPoint, &(gCurrentWindow->portRect))) {
- if (tempPoint != thePoint) {
- OffsetRect(&gShowSubRect, tempPoint.h - thePoint.h, tempPoint.v - thePoint.v);
- thePoint = tempPoint;
- }
- }
- }
- PenMode(srcCopy);
- }
- InvalRect(&gShowSubRect);
- InsetRect(checkRect, 4, 4); /* remember that ShowingRect is 4 bigger */
- InsetRect(&gShowSubRect, 4, 4); /* remember that ShowingRect is 4 bigger */
-
- if (gShowSubRect != *checkRect) { /* don't update if they didn't end up moving it */
-
-
- *checkRect = gShowSubRect; /* update our record of things */
- }
-
-
-
- subGotIt = true;
- } else {
- /* shrink it back agin */
- InsetRect(checkRect, 4, 4); /* remember that ShowingRect is 4 bigger */
-
- }
- HUnlock(*theRectsHandle);
- theRectsHandle += 1; /* increase by one Rect to check next */
- if (subGotIt)
- break;
- }
- HUnlock((*shortname)->subRects);
- }
- HUnlock((Handle)shortname);
- return(subGotIt);
- }
-
- /* end SearchSubs */
-
- /* DrawFull draws the contents of your document windows */
-
- void DrawFull(windowCHandle theWind, WindowPtr theWindPtr)
- {
- register qq;
- Rect scratchRect;
- Rect *scratchRectPtr;
- Rect grabRect;
- /* Are there any lines in this window? */
- if ((*theWind)->lineCount) { /* yes, draw 'em */
- myLine scratchLine;
- myLine *scratchPtr;
- HLock((Handle)(*theWind)->lineList); /* lock my line handle in my window data struct */
- scratchPtr = (myLine *)*((*theWind)->lineList); /* cast it to a pointer to my structure */
- for (qq = 0; qq < (*theWind)->lineCount; qq++) { /* loop through the lines */
- scratchLine = *(scratchPtr + qq); /* move the line into a temp struct */
- MoveTo(scratchLine.start.h, scratchLine.start.v); /* draw it */
- LineTo(scratchLine.end.h, scratchLine.end.v);
- }
- HUnlock((Handle)(*theWind)->lineList);
- }
- /* Any rectangles? */
- if ((*theWind)->rectCount) { /* yes, draw 'em */
- HLock((*theWind)->rectList);
- scratchRectPtr = (Rect *)*((*theWind)->rectList);
- for (qq = 0; qq < (*theWind)->rectCount; qq++) {
- scratchRect = *(scratchRectPtr + qq);
- FrameRect(&scratchRect);
- }
- HUnlock((*theWind)->rectList);
- }
- /* any ovals ? */
- if ((*theWind)->ovalCount) {
- HLock((*theWind)->ovalList);
- for (qq = 0; qq < (*theWind)->ovalCount; qq++) {
- scratchRectPtr = (Rect *)*((*theWind)->ovalList);
- scratchRect = *(scratchRectPtr + qq);
- FrameOval(&scratchRect);
- }
- HUnlock((*theWind)->ovalList);
- }
- if ((*theWind)->boxHandle != nil) {
- Rect framer;
- textSectionHandle tempTS = (*theWind)->textSections;
- TEUpdate(&(*theWind)->textBox, (*theWind)->boxHandle);
- framer = (*theWind)->textBox;
- InsetRect(&framer, -3, -2);
- FrameRect(&framer);
- /* step through any possible sections, and border them as needful */
- while (tempTS) {
- if ((*tempTS)->bordered)
- BorderTextSection(tempTS);
- tempTS = (*tempTS)->nextSection;
- }
- }
-
- /* Does the window currenlty have a selection for 'Publish'? */
- if (theWindPtr == FrontWindow()) {
- if ((*theWind)->hasSelection) {
- PenSize(1, 1);
- PenPat(qd.gray);
- FrameRect(&(*theWind)->selectionRect);
- PenPat(qd.black);
-
- }
- }
- if ((*theWind)->numSubs) { /* are we subscribed to anything? */
- PicHandle *tempHand;
- Handle *tempRHand;
- Rect *tempRect;
- HLock((*theWind)->subDataHandle); /* lock down and get the rectangles and */
- HLock((*theWind)->subRects); /* current picture data for the subscribers this */
- tempHand = (PicHandle *)*(*theWind)->subDataHandle; /* window has */
- tempRHand = (Handle *)*(*theWind)->subRects;
- /* cast them into a handy form, and step through the list, drawing each */
- for (qq = 0; qq < (*theWind)->numSubs; qq++) {
- PicHandle tempPic;
- tempPic = *tempHand;
- /* ••••This following check is important!•••• */
- /* No matter what data type you are subscribing to, the data MAY NOT */
- /* be in your application at the time you get an update. */
- /* Updates have a higher event priority than AppleEvents, and you usually */
- /* will get an update event after you show the 'Subscribe' dialog box and the */
- /* user has subscribed to something. */
- /* What that means is that you may not have yet gotten the first Section Read */
- /* event for this subscription, you have no data to display. */
- if (GetHandleSize((Handle)tempPic) != nil) {
- HLock(*tempRHand);
- tempRect = (Rect *)*(*tempRHand);
- DrawPicture(tempPic, tempRect);
- HUnlock(*tempRHand);
- }
- tempHand += 1;
- tempRHand += 1;
- }
- HUnlock((*theWind)->subDataHandle);
- HUnlock((*theWind)->subRects);
- }
- if ((*theWind)->numPicts) {
- Handle *tempPicPtr;
- Handle *tempPicRect;
- HLock((*theWind)->pictHandle);
- HLock((*theWind)->pictRects);
- tempPicPtr = (Handle *)*((*theWind)->pictHandle);
- tempPicRect = (Handle *)*((*theWind)->pictRects);
- for (qq = 0; qq < (*theWind)->numPicts; qq++) {
- HLock(*tempPicRect);
- DrawPicture((PicHandle)*tempPicPtr, (Rect *)(*(*tempPicRect)));
- tempPicPtr += 1;
- tempPicRect += 1;
- }
- }
- /* Show publisher in this window if it's been clicked on lately */
- if (theWindPtr == FrontWindow()) {
- if (gShowPub) {
- PenPat(qd.gray); /* 50% gray for publishers */
- PenSize(3, 3);
- FrameRect(&gShowPubRect);
- PenPat(qd.black);
- PenSize(1, 1);
- grabRect = gShowPubRect;
- grabRect.top = grabRect.bottom - 7;
- grabRect.left = grabRect.right - 7;
- PaintRect(&grabRect);
- /* •••• NOTE: I've taken the invert out of these areas because it got confusing for what */
- /* I was publishing and subscribing. Since we're dealing basically with bitmaps NOT */
- /* with object-style graphiocs, the invert can be confusing. */
- /* InsetRect(&gShowPubRect, 4, 4); */
- /* invert the selection */
- /* InvertRect(&gShowPubRect); */
- /* InsetRect(&gShowPubRect, -4, -4); */
- }
- if (gShowSub) {
- PenPat(qd.dkGray); /* 75% gray for subscriptions */
- PenSize(3, 3);
- InsetRect(&gShowSubRect,-4,-4);
- FrameRect(&gShowSubRect);
-
- PenPat(qd.black);
- PenSize(1, 1);
- /* same as NOTE above */
- /* InsetRect(&gShowSubRect, 4, 4); */
- /* InvertRect(&gShowSubRect); */
- /* InsetRect(&gShowSubRect, -4, -4); */
- /* add a resizing grabber */
- if (gResizeSub) {
- grabRect = gShowSubRect;
- grabRect.top = grabRect.bottom - 7;
- grabRect.left = grabRect.right - 7;
-
- PenPat(qd.black);
- if (theWindPtr != FrontWindow()) {
- EraseRect(&grabRect);
- FrameRect(&grabRect);
- } else {
- EraseRect(&grabRect);
- PaintRect(&grabRect);
- }
- }
- InsetRect(&gShowSubRect,4,4);
- }
- /* see if border showing is happening */
- /* They optionally may have the 'Show All Borders' menu item checked, if so show */
- /* the location of all the sections in this window */
- if (gShowingAll) {
- Rect borderRect;
- /* show all pubs */
- if ((*theWind)->numPubs) {
- Rect *tempRectPtr;
- HLock((*theWind)->pubRects);
- tempRectPtr = (Rect *)*(*theWind)->pubRects;
- PenPat(qd.gray); /* 50% gray for publishers */
- PenSize(3, 3);
- for (qq = 0; qq < (*theWind)->numPubs; qq++) {
- borderRect = *tempRectPtr;
- InsetRect(&borderRect, -4, -4);
- FrameRect(&borderRect);
- tempRectPtr += 1;
- }
- HUnlock((*theWind)->pubRects);
- }
-
- /* show all subs */
- if ((*theWind)->numSubs) {
-
- Handle *theRectsHandle;
- // Debugger();
- HLock((*theWind)->subRects); /* lock down the rect handle */
- /* cast it as a pointer to handles for reading ease */
- theRectsHandle = (Handle *)*(*theWind)->subRects;
-
- PenPat(qd.dkGray); /* 75% gray for subscriptions */
- PenSize(3, 3);
- for (qq = 0; qq < (*theWind)->numSubs; qq++) {
-
- HLock(*theRectsHandle);
-
- borderRect = *((Rect *)*(*theRectsHandle));
- InsetRect(&borderRect, -4, -4);
- FrameRect(&borderRect);
- HUnlock(*theRectsHandle);
- theRectsHandle += 1;
-
- }
- HUnlock((*theWind)->subRects);
-
- }
- /* and show all text sections */
- if ((*theWind)->textSections) {
- textSectionHandle tempTS = (*theWind)->textSections;
- do {
- BorderTextSection(tempTS);
- tempTS = (*tempTS)->nextSection;
- } while (tempTS);
-
- }
- PenSize(1, 1);
- PenPat(qd.black);
- }
- }
- }
-
- /* end DrawFull */
-
- /* AddLine adds a line to our window data structure */
- /* nowHandle is the window data structure handle */
- /* inLine is the line to add */
- void AddLine(windowCHandle nowHandle, myLine *inline)
- {
- Handle temphand;
- myLine *tempLinePtr;
- HLock((Handle)nowHandle);
- temphand = (Handle)(*nowHandle)->lineList;
- HUnlock((Handle)temphand);
- MySetHandleSize((Handle)temphand, (GetHandleSize(temphand) + sizeof(myLine)));
- HLock((Handle)temphand);
- tempLinePtr = (myLine *)*temphand;
- tempLinePtr += (*nowHandle)->lineCount;
- *tempLinePtr = *inline;
- (*nowHandle)->lineCount++;
- (*nowHandle)->windowDirty = true;
- HUnlock((Handle)temphand);
- HUnlock((Handle)nowHandle);
- }
-
- /* end AddLine */
-
- /* AddRect adds a rectangle to our window data structure */
- /* nowHandle is the window data structure handle */
- /* inRect is the rect to add */
- void AddRect(windowCHandle nowHandle, Rect *inrect)
- {
- Handle temphand;
- Rect *tempRectPtr;
- HLock((Handle)nowHandle);
- temphand = (*nowHandle)->rectList;
- HUnlock(temphand);
- MySetHandleSize(temphand, (GetHandleSize(temphand) + sizeof(Rect)));
- HLock(temphand);
- tempRectPtr = (Rect *)*temphand;
- tempRectPtr += (*nowHandle)->rectCount;
- *tempRectPtr = *inrect;
- (*nowHandle)->rectCount++;
- (*nowHandle)->windowDirty = true;
- HUnlock(temphand);
- HUnlock((Handle)nowHandle);
- }
-
- /* end AddRect */
-
- /* AddTextBox adds a text editing box to our window data structure */
- /* nowHandle is the window data structure handle */
- /* inRect is the position to put the box in to add */
-
- void AddTextBox(windowCHandle nowHandle, Rect *inrect)
- {
- Rect framer;
- HLock((Handle)nowHandle);
-
- (*nowHandle)->textBox = *inrect;
- (*nowHandle)->windowDirty = true;
- /* Create a TERecord to go here */
- InsetRect(&(*nowHandle)->textBox, -3, -3);
- (*nowHandle)->boxHandle = TENew(inrect, &(*nowHandle)->textBox);
- TEActivate((*nowHandle)->boxHandle);
- framer = (*nowHandle)->textBox;
- InsetRect(&framer, -3, -2);
- InvalRect(&framer);
- HUnlock((Handle)nowHandle);
- }
-
- /* end AddTextBox */
-
- /* AddOval adds a oval to our window data structure */
- /* nowHandle is the window data structure handle */
- /* inOval is the oval to add */
- void AddOval(windowCHandle nowHandle, Rect *inoval)
- {
- Handle temphand;
- Rect *tempRectPtr;
- HLock((Handle)nowHandle);
- temphand = (*nowHandle)->ovalList;
- HUnlock(temphand);
- MySetHandleSize(temphand, (GetHandleSize(temphand) + sizeof(Rect)));
- HLock(temphand);
- tempRectPtr = (Rect *)*temphand;
- tempRectPtr += (*nowHandle)->ovalCount;
- *tempRectPtr = *inoval;
- (*nowHandle)->ovalCount++;
- (*nowHandle)->windowDirty = true;
- HUnlock(temphand);
- HUnlock((Handle)nowHandle);
- }
-
- /* end AddOval */
-
- /* AddSelection adds a selection rectangle to our window data structure */
- /* nowHandle is the window data structure handle */
- /* inRect is the rect to add */
- void AddSelection(windowCHandle nowHandle, Rect *inrect)
- {
- HLock((Handle)nowHandle);
- (*nowHandle)->selectionRect = *inrect;
- (*nowHandle)->hasSelection = true;
- HUnlock((Handle)nowHandle);
- }
-
- /* end AddSelection */
-
-
-
- /* ShowMe is just a handy place to display a string and a number. */
- void ShowMe(Str255 in, OSErr aevtErr)
- {
- Str255 theGuy;
- InitCursor();
- NumToString((long)aevtErr, theGuy);
- ParamText(in, theGuy, "\p ", "");
- Alert(129, nil);
- }
-
- /* DoDiskEvents just checks the error code from the disk mount, */
- /* and puts up the 'Format' dialog (through DIBadMount) if need be */
- /* You can do much more here if you care about what disks are */
- /* in the drive */
- void DoDiskEvents(long dinfo) /* hi word is error code, lo word is drive number */
- {
- short hival, loval, tommy;
- Point fredpoint = {
- 40, 40
- };
- hival = HiWord(dinfo);
- loval = LoWord(dinfo);
- if (hival != noErr) /* something happened */ {
- tommy = DIBadMount(fredpoint, dinfo);
- }
- }
-
- /* AdjustCursor taken pretty much from TrafficLight, modified to use our cursors */
- /* and to use local coordinates this time, for variety */
- /* Change the cursor's shape, depending on its position. This also calculates
- the region where the current cursor resides (for WaitNextEvent). If the
- mouse is ever outside of that region, an event would be generated, causing
- this routine to be called, allowing us to change the region to the region
- the mouse is currently in. If there is more to the event than just “the
- mouse moved”, we get called before the event is processed to make sure the
- cursor is the right one. In any (ahem) event, this is called again before
- we fall back into WNE.
-
-
- */
-
- void AdjustCursor(Point mouse, RgnHandle region, Boolean isAppleEvent)
- {
- WindowPtr window, tempWindow;
- RgnHandle specialRgn;
- Rect globalPortRect;
- windowCHandle shortName;
- window = FrontWindow(); /* we only adjust the cursor when we are in front */
- if (window == gClipWindowPtr) {
- InitCursor();
- return;
- }
- if (gWindowCount == 0)
- return; /* ignore also if we have no open doc windows */
- if ((!gInBackground) && (!IsDAWindow(window))) {
- if (isAppleEvent)
- return; /* do no cursoring on AppleEvents */
- GetPort(&tempWindow);
- SetPort(window);
- /* calculate regions for different cursor shapes */
- specialRgn = NewRgn();
- /* calculate specialRgn */
- globalPortRect = window->portRect;
- RectRgn(specialRgn, &globalPortRect);
- SectRgn(specialRgn, window->visRgn, specialRgn);
- /* change the cursor and the region parameter */
- GlobalToLocal(&mouse);
- if (PtInRgn(mouse, specialRgn)) {
- short temp;
- shortName = (windowCHandle)GetWRefCon(window);
- temp = actsToIDs[(*shortName)->currentAction];
- SetMyCursor(temp);
- CopyRgn(specialRgn, region);
- } else { /* outside */
- SetCursor(&qd.arrow);
- }
- /* get rid of our local regions */
- DisposeRgn(specialRgn);
- SetPort(tempWindow);
- }
- }
-
- /* end AdjustCursor*/
-
-
- /* PullRect draws the rectangle or oval shape, and also resizes subscriptions */
- void PullRect(windowCHandle theWind, Rect *startRect, Boolean isOval, Boolean useRect)
- {
- Rect oldRect;
- Point endPoint;
- Rect tempHold;
- if (useRect) {
- oldRect = *startRect;
- } else {
- oldRect.top = startRect->top = oldRect.bottom = startRect->bottom = gERecord.where.v;
- oldRect.right = startRect->right = oldRect.left = startRect->left = gERecord.where.h;
- }
- tempHold = oldRect;
- PenMode(srcXor); /* So we can rubberband */
- while (StillDown()) { /* Keep doing this as long as the */
- /* user keeps the mouse down */
- GetMouse(&endPoint); /* Current mouse position in local */
- /* coordinates */
- startRect->right = endPoint.h;
- startRect->bottom = endPoint.v;
- if (!InTextBox(theWind, startRect)) {
- if (*startRect != oldRect) { /* redraw the rect only if the mouse moved */
- if (isOval) {
- FrameOval(&oldRect); /* Erase (overdraw in Xor) the old oval */
- FrameOval(startRect);
- } else {
- FrameRect(&oldRect); /* Erase (overdrw in Xor) the old rect */
- FrameRect(startRect); /* draw the new rect */
- }
- oldRect = *startRect;
- }
- }
- }
- PenMode(srcCopy);
- /* don't let them shrink a subscriber 'til it disappears */
- if (((startRect->right - startRect->left) < 15) || ((startRect->bottom - startRect->top) < 15))
- *startRect = tempHold;
- }
-
- /* DoDocumentClick handles clicking in the content region of our */
- /* document windows. */
- void DoDocumentClick(WindowPtr twindow)
- {
-
- /* if the window already was frontmost, take the right */
- /* action for this window */
- /* ••• NOTE: Normally, this is also the place where you would */
- /* update the modification date (mdDate) of publishers */
- /* If the user takes an action across a published area, you */
- /* should update the modification time to flag yourself that this */
- /* edition needs to be sent. This date/time will also show up in the */
- /* Options dialog for that publisher. But for the sake of clarity in this */
- /* sample, I am only changing the mod date on edition write (in files.c) */
- Point endPoint;
- Point oldendPoint;
- Rect startRect;
- Boolean wasInTB;
- windowCHandle shortname;
- short tempAct;
- Rect testRect;
- gCurrentWindow = twindow;
- shortname = (windowCHandle)GetWRefCon(gCurrentWindow);
- /* This handle is already locked on entry, from the dispatcher that got us here */
-
- tempAct = (*shortname)->currentAction; /* what are they doing? */
- SetPort(gCurrentWindow); /* make sure the port is good, I'm paranoid */
- GlobalToLocal(&gERecord.where); /* everything will be in local coordinate to this window */
- /* I don't want users to draw objects across my text box, so see if this click is in that thang */
- testRect.left = testRect.right = gERecord.where.h;
- testRect.right++;
- testRect.top = testRect.bottom = gERecord.where.v;
- testRect.bottom++;
- wasInTB = InTextBox(shortname, &testRect);
- if (!wasInTB || tempAct == kTextBox || tempAct == kNoAction) {
- switch (tempAct) { /* switch off the action code */
- myLine tempLine;
- case kNoAction:
- /* no menu items checked. See if they clicked in a */
- /* publisher or subcriber */
- /* border a publisher or subscriber if they clicked in one */
- if (!SearchPubs(gERecord.where) && !SearchSubs(gERecord.where)) {
- /* if they didn't click in one, then erase the current selection */
- /* Check to see if they're clicking in the TERecord. This takes precidence over */
- /* any other click */
- if (wasInTB) {
- /* treat this like a random click to de-border any PICT subscriptions that */
- /* may be selected */
-
- DeBorderSelection();
- /* check publisher stuff here */
- TEClick(gERecord.where, gERecord.modifiers & shiftKey, (*shortname)->boxHandle);
- if (!gShowingAll) {
- textSectionHandle tempTS = (*shortname)->textSections;
- Boolean anyOn = false; /* for our invalidate check */
- /* step through text sections and turn off flags */
- // while (tempTS) {
- // /* also check here to see if anything was bordered. If it was, invalidate */
- // /* the TE rectangle so the old borders will be erased. If there */
- // /* were NOT any, don't invalidate, so we don't strobe the user to */
- // /* blindness */
- // anyOn = anyOn | (*tempTS)->bordered;
- // (*tempTS)->bordered = false;
- // tempTS = (*tempTS)->nextSection;
- // }
- // if (anyOn)
- // InvalRect(&(*(*shortname)->boxHandle)->viewRect);
- } /* see if the click was inside a subscriber */
- CheckSectionHit();
-
- } else {
- /* if it was a random click, dehilite the text selection if there is one */
- if ((*shortname)->boxHandle != nil) {
- TESetSelect((*(*shortname)->boxHandle)->selStart, (*(*shortname)->boxHandle)->selStart,
- (*shortname)->boxHandle);
- /* Also, check to see if any borders are on in the TE box. If so, turn them off. */
- /* That is, unless gSHowingAll is on.... */
- /* and it's easiest just to invlaidate the terect */
- InvalRect(&(*(*shortname)->boxHandle)->viewRect);
- if (!gShowingAll) {
- textSectionHandle tempTS = (*shortname)->textSections;
- /* step through text sections and turn off flags */
- while (tempTS) {
- (*tempTS)->bordered = false;
- tempTS = (*tempTS)->nextSection;
- }
- }
- }
- DeBorderSelection();
- }
- break;
- case kDrawLine:
- /* they want to draw a line in this window */
- /* start and end points of the line set to the same val */
- oldendPoint = endPoint = gERecord.where;
- PenMode(srcXor); /* Xor so we can rubberband the line */
- while (StillDown()) { /* Keep doing this as long as the */
- /* user keeps the mouse down */
- GetMouse(&endPoint); /* Current mouse position in local */
- MakeRect(&gERecord.where, &endPoint, &testRect);
- if (!InTextBox(shortname, &testRect)) {
- /* coordinates */
- if (endPoint != oldendPoint) { /* only do this if the mouse moved so the line doesn't flicker */
- /* erase the old line (redraw in Xor mode ) */
- MoveTo(gERecord.where.h, gERecord.where.v);
- LineTo(oldendPoint.h, oldendPoint.v);
- /* draw the new line */
- MoveTo(gERecord.where.h, gERecord.where.v);
- LineTo(endPoint.h, endPoint.v);
- oldendPoint = endPoint;
- }
- }
- } /* StillDown while */
- PenMode(srcCopy);
- /* They released the mouse. Add the line they drew */
- /* to our record */
- tempLine.start = gERecord.where;
- tempLine.end = endPoint;
- /* see this function later in this file */
- AddLine((windowCHandle)((WindowPeek)gCurrentWindow)->refCon, &tempLine);
- /* changes the Undo menu item text */
- SetUndo(kDrawLine, false);
- break; /* end line case */
-
- /* they want to draw a rectangle in this window */
- case kDrawRect:
- /* start and end of rectangle set to the same val */
- PullRect(shortname, &startRect, false, false);
- /* Add it to our window */
- AddRect((windowCHandle)((WindowPeek)gCurrentWindow)->refCon, &startRect);
- SetUndo(kDrawRect, false); /* Set undo menu item text to */
- /* Undo Rectangle */
- break; /* end rectangle case */
-
- case kDrawOval:
- /* start and end of oval set to the same val */
- PullRect(shortname, &startRect, true, false);
- /* Add the oval to our window struct */
- AddOval((windowCHandle)((WindowPeek)gCurrentWindow)->refCon, &startRect);
- /* Set undo menu item text to Undo Oval */
- SetUndo(kDrawOval, false);
- break;
- case kTextBox:
- /* start and end of rectangle set to the same val */
- PullRect(shortname, &startRect, false, false);
- /* Add it to our window */
- AddTextBox((windowCHandle)((WindowPeek)gCurrentWindow)->refCon, &startRect);
- SetUndo(kCantUndo, false); /* can't undo a text box */
- SwitchChecks(kTextBox);
- InitCursor();
- /* Undo Rectangle */
- break;
- case kSelectStuff:
- /* pretty much like drawrect, but */
- /* the resulting rect can be published */
- PullRect(shortname, &startRect, false, false);
- PenPat(qd.gray);
- FrameRect(&startRect);
- PenPat(qd.black);
- PenSize(1, 1);
- AddSelection((windowCHandle)((WindowPeek)gCurrentWindow)->refCon, &startRect);
- /* they can only select one rectangle, so clear the check */
- /* and change the cursor back to an arrow */
- SwitchChecks(kSelectStuff);
- InitCursor();
- gHasSelection = true; /* flagging a selection available, see right */
- SetUndo(kSelectItem - 1, false); /* since the item on the menu is one more than our use, because of the divider */
- /* before the MenuSelect call above to see how it's used */
- break;
- break;
- } else {
- unsigned long timeNow;
- /* they did click in one, see if it is/was a double click please */
- if ((gShowingSecHandle == lastSection) && (gShowingSecHandle != nil)) {
- timeNow = TickCount();
- if ((timeNow - lastSecClickTick) < GetDblTime()) {
- /* it is a double click. treat the same way as the menu selection for Options */
- if (gERecord.modifiers & optionKey)
- MyGoToPublisher(lastSection);
- else
- DoOptions(gShowingSecHandle); /* in Subscribe.c. */
-
- } else {
- /* not a double click. Set up for the next pass */
- lastSecClickTick = timeNow;
- lastSection = gShowingSecHandle;
- }
- } else {
- lastSecClickTick = timeNow;
- lastSection = gShowingSecHandle;
- }
- }
- }
- }
- }
-
- /* end DoDocumentClick */
-
- /* Various clipboard handling routines */
- #pragma segment Main
-
- /* This tries as hard as it can to resize a handle, avoiding the problem SetHandleSize */
- /* has when a block is surrounded by locked stuff. */
- /* Of course if you use this, you can only have one copy of the handle around and you */
- /* always must reference that handle, since the master pointer contained within it */
- /* can change during the ReallocHandle call. But you should be doing that anyway (nag nag nag) */
- OSErr MySetHandleSize(Handle theHandle, Size theSize)
- {
- OSErr memErr;
- char state;
- Handle tempHand = theHandle;
- SetHandleSize(theHandle, theSize);
- memErr = MemError();
- if (!memErr)
- return(noErr);
- /* could not resize the handle. Why? */
- if (memErr != memFullErr)
- return(memErr); /* not something we can deal with */
- /* either the memory is really not available, or there is a locked pointer
- * above the handle we're resizing. We'll try seeing if the memory
- * is actually there first. */
- ShowMe("\p mem err", memErr);
- if (!(CompactMem(theSize) >= theSize))
- return(MemError()); /* memory really is full, bail */
- /* OK, memory is available somewhere. Find it */
- HandToHand(&tempHand); /* copy the handle */
- ReallocHandle(theHandle, theSize); /* resize by reallocation */
- HLock(tempHand);
- HLock(theHandle);
- BlockMove(*tempHand, *theHandle, GetHandleSize(theHandle)); /* only move the size of the target */
- HUnlock(theHandle);
- DisposHandle(tempHand);
- }
-
-
-
- /* InTextBox tells us if the rectangle passed intersects the text rectangle */
- /* in the current window. We use this for; */
- /* 1) Seeing if the mouse click was in the TERect, so we can call TEClick */
- /* 2) See if one of our drawing commands will overdraw the text, which is BaD */
- Boolean InTextBox(windowCHandle inName, Rect *where)
- {
- Rect temp;
- if ((*inName)->boxHandle == nil) {
- return(false);
- } else {
- return(SectRect(where, &(*inName)->textBox, &temp));
- }
- }
-
- /* MakeRect converts two points into a rect. */
- void MakeRect(Point *aPoint, Point *bPoint, Rect *putRect)
- {
- short temp;
- putRect->top = aPoint->v;
- putRect->left = aPoint->h;
- putRect->bottom = bPoint->v;
- putRect->right = bPoint->h;
- if (putRect->top > putRect->bottom) {
- temp = putRect->bottom;
- putRect->bottom = putRect->top;
- putRect->top = temp;
- }
- if (putRect->left > putRect->right) {
- temp = putRect->right;
- putRect->right = putRect->left;
- putRect->left = temp;
- }
- if (putRect->right == putRect->left)
- putRect->left++;
- if (putRect->bottom == putRect->top)
- putRect->bottom++;
- }
-
-
-
-
- void AppendString(Str255 target, Str255 appendIt)
- {
- BlockMove((Ptr)(appendIt + 1), (Ptr)(target + (target[0])+1), appendIt[0]);
- target[0] += appendIt[0];
- }
-
- Boolean PureCursor(char theKey)
- {
- register qq;
- char curChars[4] = {
- kLeftArrow, kRightArrow, kUpArrow, kDownArrow
- };
- Boolean result = false;
- for (qq = 0; qq < 4; qq++) {
- if (theKey == curChars[qq])
- result = true;
- }
- return(result);
-
- }
-
- void DeBorderSelection(void)
- {
- if (gShowPub) {
- gShowPub = false;
- gShowingSecHandle = nil;
- InvalRect(&gShowPubRect);
- } else {
- if (gShowSub) {
- gShowSub = false;
- gShowingSecHandle = nil;
- InvalRect(&gShowSubRect);
- }
- }
- }
-
-
-
- #pragma segment MyInit
- /* StartStuff initializes the managers and does some other init stuff */
- void StartStuff(void)
- {
- extern void StartMenus();
- MaxApplZone();
- InitGraf((Ptr)&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- MoreMasters();
- /* See if AppleEvents and the Edition manager are available */
- InitAEStuff(); /* In AppleEventM.c */
- gHasEditionManager = (Gestalt(gestaltEditionMgrAttr, &aLong) == noErr);
- if (gHasEditionManager) {
- InitEditionPack();
- /* set up my opener routine, will be implemented later */
- /* GetEditionOpenerProc(&gOriginalOpener);
- SetEditionOpenerProc((EditionOpenerProcPtr)OpenMyFiles);
- */
-
- } else {
- Alert(kNoEditionManager, nil); /* tell 'em and exit */
- ExitToShell();
- }
- GetCurrentProcess(&gOurSN); /* grab our applications process serial number */
- /* so we can communicate (send appleevents) to */
- /* ourself easily */
- StartMenus(); /* load the menu bar and set up the menus */
- CreateClipBoard();
- /* ••• NOTE: I am not opening a document window here. The application will wait for an */
- /* OAPP AppleEvent before opening a window. This makes it a whole lot easier */
- /* to deal with ODOC events, since you needn't special case anything */
- }
-
- /* end StartStuff */
-
- /* CreateClipBoard creates our invisible clipboard window at application */
- /* start time, and keeps it open always. Visibility is toggled from the edit menu, */
- /* but the window always exists */
- void CreateClipBoard(void)
- {
- windowCHandle tempWC;
-
- /* open my clipboard window */
- gClipWindowPtr = GetNewWindow(kClipWindow, 0, (WindowPtr)-1);
-
- /* since I'm using the same function for my clipboard as for a document window, I have */
- /* to change some of the fields */
- ((WindowPeek)gClipWindowPtr)->refCon = NewHandle(sizeof(windowControl)); /* add our control structure to it */
- tempWC = (windowCHandle)GetWRefCon(gClipWindowPtr); /* and put it where we can use it */
- HLock((Handle)tempWC); /* lock it down */
- /* add pointers to our procedures for drawing, saving, and closing */
- (*tempWC)->drawMe = (ProcPtr)DrawClip;
- (*tempWC)->saveMe = (ProcPtr)nil;
- (*tempWC)->closeMe = (ProcPtr)CloseClip;
- (*tempWC)->clickMe = (ProcPtr)ClipClick;
- (*tempWC)->lineCount = nil;
- (*tempWC)->rectCount = nil;
- (*tempWC)->ovalCount = nil;
- (*tempWC)->currentAction = nil;
- (*tempWC)->undoAction = nil;
- (*tempWC)->hasSelection = false;
- (*tempWC)->windowDirty = false;
- (*tempWC)->boxHandle = nil;
- (*tempWC)->textSections = nil;
- gScrapData = NewHandle(0);
- UpdateScrap();
- }
-
- /* end CreateClipBoard */
-
-
- #undef __SAMPMAIN__
-